<!--export default class CallState {-->
<!--static STATUS_IDLE = 0;-->
<!--static STATUS_OUTGOING = 1;-->
<!--static STATUS_INCOMING = 2;-->
<!--static STATUS_CONNECTING = 3;-->
<!--static STATUS_CONNECTED = 4;-->
<!--}-->
<template>
    <div class="flex-column flex-align-center flex-justify-center voip-container" ref="rootContainer">
        <div v-if="sharedMiscState.isElectron" ref="notClickThroughArea">
            <ElectronWindowsControlButtonView style="position: absolute; top: 0; left: 0; width: 100%; height: 30px; background: white"
                                              :title="'野火会议'"
                                              :macos="!sharedMiscState.isElectronWindowsOrLinux"/>
            <ScreenShareControlView v-if="session && session.isScreenSharing()" type="conference"/>
            <h1 style="display: none">Voip-Conference 运行在新的window，和主窗口数据是隔离的！！</h1>
        </div>
        <div v-if="endReason !== undefined && endReason === 4" @click="rejoinConference" class="rejoin-container">
            会议断开，点击重新加入
        </div>
        <div v-if="session" class="main-slider-container"
             v-bind:style="{display: session.isScreenSharing() && sharedMiscState.isElectron ? 'none' : 'flex'}">
            <div class="main">
                <header style="background: white; height: 20px; display: flex; justify-content: space-between">
                    <a href="#">
                        <i class="icon-ion-information" style="padding: 0 10px"
                           id="info-icon"
                           v-bind:class="{active:showConferenceSimpleInfoView}"
                           @click="showConferenceSimpleInfoView = !showConferenceSimpleInfoView"/>
                    </a>
                    <p style="flex: 1"></p>
                    <p style="padding-right: 10px">{{ duration }}</p>
                    <div>
                        <a v-if="!audioOnly" href="#">
                            <i class="icon-ion-grid" style="padding: 0 10px"
                               id="grid-icon"
                               v-bind:class="{active:showChooseLayoutView}"
                               @click="showChooseLayoutView = !showChooseLayoutView">宫格布局</i>
                        </a>
                        <!--                        TODO 条件显示，展示聊天界面，或者参与者列表界面时，才展示-->
                        <a href="#" v-if="showSlider">
                            <i :class="showSlider? 'icon-ion-arrow-left-b' : 'icon-ion-arrow-right-b'" style="padding: 0 10px" @click="toggleSliderView"></i>
                        </a>
                    </div>
                </header>
                <div v-if="showConferenceSimpleInfoView"
                     v-click-outside="hideConferenceSimpleInfoView"
                     style="position: absolute; left: 10px; top: 50px; z-index: 1000">
                    <ConferenceSimpleInfoView
                        :session="session"
                    />
                </div>
                <div v-if="showChooseLayoutView"
                     v-click-outside="hideChooseLayoutView"
                     style="position: absolute; right: 10px; top: 50px; z-index: 1000">
                    <ChooseConferenceLayoutView
                        :current-layout="computedCurrentLayout"
                        :session="session"/>
                </div>
                <div style="position: absolute; left: 10px; bottom: 80px; width: 300px; max-height: 300px; overflow: hidden; background: transparent; z-index: 1000">
                    <ConferenceConversationFloatingView
                        :session="session"
                    />
                </div>
                <div class="conference-main-content-container">
                    <!--main-->
                    <!--video-->
                    <div v-if="!audioOnly" style="width: 100%; height: 100%">
                        <i v-if="computedCurrentLayout=== 0 && currentGridPageIndex > 0" style="position: absolute; top: 50%; left: 0; color: #c8cacc; z-index: 1000; font-size: 40px; padding: 0 10px" class="icon-ion-arrow-left-c"
                           @click="prePage"></i>
                        <i v-if="computedCurrentLayout=== 0 && currentGridPageIndex < gridPageCount - 1" style="position: absolute; top: 50%; right: 0; color: #c8cacc; z-index: 1000; font-size: 40px; padding: 0 10px" class="icon-ion-arrow-right-c"
                           @click="nextPage"></i>
                        <!--                    宫格布局-->
                        <section v-if="computedCurrentLayout=== 0" class="content-container grid video">
                            <!--participants include self-->
                            <ConferenceParticipantVideoView v-for="(participant) in currentPageParticipants"
                                                            :key="participant.uid + '-' + participant._isScreenSharing"
                                                            :participant="participant"
                                                            :session="session">
                            </ConferenceParticipantVideoView>
                        </section>

                        <!--                    演讲者布局-->
                        <section v-else class="content-container focus video">
                            <div :style="{width: hideFocusLayoutParticipantListVideoView ? '100%' : 'calc(100% - 200px)', height: '100%', position: 'relative'}">
                                <video v-if=" computedFocusVideoParticipant && !computedFocusVideoParticipant._isAudience && !computedFocusVideoParticipant._isVideoMuted && computedFocusVideoParticipant._stream"
                                       v-bind:style="{objectFit:computedFocusVideoParticipant._isScreenSharing ? 'contain' : 'fit'}"
                                       style="width: 100%; height: 100%"
                                       :srcObject.prop="computedFocusVideoParticipant._stream"
                                       :muted="computedFocusVideoParticipant.uid === selfUserInfo.uid"
                                       playsInline
                                       autoPlay/>
                                <div @click="toggleParticipantListVideoView" style="position: absolute; top: 50%; right: 0; color: #c8cacc; z-index: 1000; font-size: 40px">
                                    <i :class="hideFocusLayoutParticipantListVideoView ? 'icon-ion-arrow-left-b' : 'icon-ion-arrow-right-b'"></i>
                                </div>
                            </div>
                            <div v-show="!hideFocusLayoutParticipantListVideoView" class="focus-mode-participant-list-container">
                                <!--participants include self-->
                                <ConferenceParticipantVideoView v-for="(participant) in participantUserInfos"
                                                                :key="participant.uid + '-' + participant._isScreenSharing"
                                                                :participant="participant"
                                                                :session="session">
                                </ConferenceParticipantVideoView>
                            </div>
                        </section>
                    </div>
                    <!--audio-->
                    <div v-else style="width: 100%; height: 100%">
                        <div
                            style="background: white; height: 50px; display: flex; justify-content: center; align-items: center">
                            <div
                                style="background: #daeafe; width: 300px; height: 40px; padding: 0 5px; border-radius: 3px; display: flex; flex-direction: column; justify-content: center">
                                <p class="single-line"> {{ '正在讲话: ' + speakingUserName }}</p>
                            </div>
                        </div>
                        <section class="content-container audio">
                            <!--participants-->
                            <div v-for="(participant) in participantUserInfos"
                                 :key="participant.uid"
                                 class="participant-audio-item">
                                <video v-if="audioOnly && participant._stream && !participant._isVideoMuted"
                                       class="hidden-video"
                                       controls
                                       :srcObject.prop="participant._stream"
                                       :muted="participant.uid === selfUserInfo.uid"
                                       playsInline autoPlay/>
                                <audio v-else-if="audioOnly && participant._stream && participant._isVideoMuted"
                                       class="hidden-video"
                                       controls
                                       :srcObject.prop="participant._stream"
                                       :ref="participant.uid + '-audio'"
                                       :muted="participant.uid === selfUserInfo.uid"
                                       playsInline autoPlay/>
                                <div style="position: relative">
                                    <img class="avatar"
                                         v-bind:class="{highlight:participant._volume > 0}"
                                         :src="participant.portrait" :alt="participant">
                                    <i v-if="participant._isHost" class="indicator icon-ion-person" style="background: #FD802E"></i>
                                    <i v-if="participant._isAudience" class="indicator icon-ion-ios-mic-off" style="color: red"></i>
                                </div>
                                <p class="single-line">{{ userName(participant) }}</p>
                            </div>
                        </section>
                    </div>
                    <!--actions-->
                    <footer>
                        <div class="duration-action-container">
                            <p v-if="false">{{ duration }}</p>
                            <div class="action-container">
                                <div class="action">
                                    <img v-if="!session.audience && !session.audioMuted" @click="muteAudio" class="action-img"
                                         src='@/assets/images/av_conference_audio.png'/>
                                    <img v-else @click="muteAudio" class="action-img"
                                         src='@/assets/images/av_conference_audio_mute.png'/>
                                    <p>静音</p>
                                </div>
                                <div class="action"
                                     v-if="!session.isScreenSharing()">
                                    <img v-if="!session.audience && !session.videoMuted" @click="muteVideo" class="action-img"
                                         src='@/assets/images/av_conference_video.png'/>
                                    <img v-else @click="muteVideo" class="action-img"
                                         src='@/assets/images/av_conference_video_mute.png'/>
                                    <p>视频</p>
                                </div>
                                <div class="action">
                                    <img v-if="!session.screenSharing" @click="screenShare"
                                         class="action-img"
                                         src='@/assets/images/av_conference_screen_sharing.png'/>
                                    <img v-else @click="screenShare" class="action-img"
                                         src='@/assets/images/av_conference_screen_sharing_hover.png'/>
                                    <p class="single-line">共享屏幕</p>
                                </div>
                                <div v-if="sharedMiscState.isElectron" class="action" @click="chat">
                                    <i class="icon-ion-ios-chatboxes"
                                       style="width: 40px; height: 40px; font-size: 40px; color: black"
                                       v-bind:style="{color: showConversationView ? 'white' : 'black'}"/>
                                    <p>聊天</p>
                                </div>
                                <div v-if="selfUserInfo.uid !== conferenceManager.conferenceInfo.owner" class="action">
                                    <img v-if="!conferenceManager.isHandUp" @click="handup"
                                         class="action-img"
                                         src='@/assets/images/av_conference_handup.png'/>
                                    <img v-else @click="handup" class="action-img"
                                         src='@/assets/images/av_conference_handup_hover.png'/>
                                    <p class="single-line">举手</p>
                                </div>
                                <div class="action">
                                    <img @click.stop="members" class="action-img"
                                         v-bind:style="{filter: showConferenceManageView ? 'invert(100%)' : 'none'}"
                                         src='@/assets/images/av_conference_members.png'/>
                                    <p>管理</p>
                                </div>
                                <div class="action">
                                    <img @click="hangup" class="action-img"
                                         src='@/assets/images/av_conference_end_call.png'/>
                                    <p>结束</p>
                                </div>
                            </div>
                        </div>
                    </footer>
                </div>

            </div>
            <div class="slider">
                <div class="title" style="display: none">
                    TODO
                </div>
                <ConferenceManageView
                    v-if="showConferenceManageView"
                    v-bind:class="{ active: showConferenceManageView}"
                    :participants="participantUserInfos"
                    :session="session"
                />
                <ConversationView v-if="showConversationView"
                                  class="conversation-view"
                                  style="height: 100%"
                                  :title="conferenceManager.conferenceInfo.conferenceTitle"
                                  :input-options="{disableScreenShot:true, disableHistory:true, disableVoip:true, disableChannelMenu:true}"/>
            </div>
        </div>
    </div>
</template>

<script>
import avenginekit from "../../../wfc/av/internal/engine.min";
import CallSessionCallback from "../../../wfc/av/engine/callSessionCallback";
import CallState from "@/wfc/av/engine/callState";
import IpcSub from "../../../ipc/ipcSub";
import ClickOutside from 'vue-click-outside'
import localStorageEmitter from "../../../ipc/localStorageEmitter";
import {currentWindow, isElectron, remote} from "../../../platform";
import ScreenOrWindowPicker from "../ScreenOrWindowPicker";
import CallEndReason from "../../../wfc/av/engine/callEndReason";
import ScreenShareControlView from "../ScreenShareControlView";
import avenginekitproxy from "../../../wfc/av/engine/avenginekitproxy";
import ElectronWindowsControlButtonView from "../../common/ElectronWindowsControlButtonView";
import store from "../../../store";
import VideoType from "../../../wfc/av/engine/videoType";
import IpcEventType from "../../../ipcEventType";
import ConferenceParticipantVideoView from "./ConferenceParticipantVideoView";
import ConversationView from "../../main/conversation/ConversationView";
import ConferenceSimpleInfoView from "./ConferenceSimpleInfoView";
import ChooseConferenceLayoutView from "./ChooseConferenceLayoutView";
import ConferenceConversationFloatingView from "./ConferenceConversationFloatingView";
import conferenceManager from "./conferenceManager";
import ConferenceManageView from "./ConferenceManageView";

export default {
    name: 'Conference',
    data() {
        return {
            session: null,
            audioOnly: false,
            status: 1,
            selfUserInfo: null,
            participantUserInfos: [],

            startTimestamp: 0,
            currentTimestamp: 0,

            showSlider: false,
            showConferenceManageView: false,
            showConversationView: false,
            sharedMiscState: store.state.misc,
            videoInputDeviceIndex: 0,

            refreshUserInfoInternal: 0,

            endReason: undefined,

            conferenceManager: conferenceManager,

            // -1，默认布局，也就是宫格布局；0, 宫格视图；1，演讲者视图
            currentLayout: -1,

            // 宫格视图
            currentGridPageIndex: 0,
            participantCountPerGridPage: 9,

            // 演讲者视图
            speakingVideoParticipant: null,
            hideFocusLayoutParticipantListVideoView: false,

            showConferenceSimpleInfoView: false,
            showChooseLayoutView: false,
        }
    },
    components: {
        ConferenceManageView,
        ConferenceConversationFloatingView,
        ChooseConferenceLayoutView,
        ConferenceSimpleInfoView,
        ConferenceParticipantVideoView,
        ScreenShareControlView,
        ElectronWindowsControlButtonView,
        ConversationView
    },
    methods: {
        setupSessionCallback() {
            let sessionCallback = new CallSessionCallback();

            sessionCallback.didChangeState = (state) => {
                console.log('didChangeState', state)
                this.status = state;
                if (state === CallState.STATUS_CONNECTED) {
                    if (this.startTimestamp === 0) {
                        this.startTimestamp = new Date().getTime();
                        this.timer = setInterval(() => {
                            this.currentTimestamp = new Date().getTime();
                        }, 1000)
                    }
                } else if (state === CallState.STATUS_IDLE) {
                    if (this.timer) {
                        clearInterval(this.timer);
                    }
                }
            };

            sessionCallback.onInitial = (session, selfUserInfo, initiatorUserInfo) => {
                //this.session.rotateAng = 90;

                selfUserInfo._isHost = session.host === selfUserInfo.uid;
                selfUserInfo._isAudience = session.audience;
                selfUserInfo._isVideoMuted = session.videoMuted;
                selfUserInfo._isAudioMuted = session.audioMuted;
                selfUserInfo._volume = 0;
                // 修添加属性，在赋值，才能 reactive
                this.selfUserInfo = selfUserInfo;
                this.participantUserInfos = [selfUserInfo];

                console.log('oninitial', selfUserInfo._isAudience)
                // pls refer to: https://vuejs.org/v2/guide/reactivity.html
                this.$set(this.selfUserInfo, '_stream', null);
                this.participantUserInfos.forEach(p => this.$set(p, "_stream", null))

                this.session = session;
                document.title = session.title;

                conferenceManager.getConferenceInfo(session.callId);
            };

            sessionCallback.didCreateLocalVideoTrack = (stream) => {
                this.selfUserInfo._stream = stream;
            };

            sessionCallback.didRotateLocalVideoTrack = (stream) => {
                console.log('didRotateLocalVideoTrack', stream.getAudioTracks())
                this.selfUserInfo._stream = stream;
            };

            sessionCallback.didCreateLocalVideoTrackError = () => {
                // TODO
                // 没有摄像头或者麦克风，加入会议时，会回调到此处，自己断会显示自己的头像，其他端会显示黑屏
                // 可以进行相关提示
            };

            sessionCallback.didReceiveRemoteVideoTrack = (userId, stream, screenSharing) => {
                let p;
                console.log('didReceiveRemoteVideoTrack', userId, stream, screenSharing);
                for (let i = 0; i < this.participantUserInfos.length; i++) {
                    p = this.participantUserInfos[i];
                    if (p.uid === userId && p._isScreenSharing === screenSharing) {
                        p._stream = stream;
                        break;
                    }
                }
            };

            sessionCallback.didRemoveRemoteVideoTrack = (userId) => {

            };

            sessionCallback.didParticipantJoined = (userId, screenSharing) => {
                console.log('didParticipantJoined', userId, screenSharing)
                IpcSub.getUserInfos([userId], null, (userInfos) => {
                    let userInfo = userInfos[0];
                    let subscriber = this.session.getSubscriber(userId, screenSharing);
                    userInfo._stream = subscriber.stream;
                    userInfo._isAudience = subscriber.audience;
                    userInfo._isHost = this.session.host === userId;
                    userInfo._isVideoMuted = subscriber.videoMuted;
                    userInfo._isAudioMuted = subscriber.audioMuted;
                    userInfo._volume = 0;
                    userInfo._isScreenSharing = screenSharing;
                    this.participantUserInfos.push(userInfo);
                    console.log('joined', userInfos, subscriber.audience, this.participantUserInfos.length);
                })
            }

            sessionCallback.didParticipantLeft = (userId, endReason, screenSharing) => {
                console.log('didParticipantLeft', userId, endReason, screenSharing, JSON.stringify(this.participantUserInfos), this.participantUserInfos.length)
                //this.participantUserInfos = this.participantUserInfos.filter(p => p.uid !== userId && p._isScreenSharing !== screenSharing);
                this.participantUserInfos = this.participantUserInfos.filter(p => {
                    return !(p.uid === userId && p._isScreenSharing === screenSharing);
                });
                console.log('didParticipantLeft d', userId, endReason, screenSharing, this.participantUserInfos.length)
            }

            sessionCallback.didCallEndWithReason = (reason) => {
                console.log('callEndWithReason', reason)
                // 可以根据reason，进行一些提示
                // alert('会议已结束');

                this.endReason = reason;
                if (reason === CallEndReason.REASON_MediaError) {
                    return;
                }
                if (reason === CallEndReason.RoomNotExist) {
                    console.log('join conference failed', reason, this.session)
                    let obj = {reason: reason, session: this.session};
                    localStorageEmitter.send('join-conference-failed', obj);
                }
                this.session.closeVoipWindow();
                this.session = null;
            }

            sessionCallback.onRequestChangeMode = (userId, audience) => {
                console.log('onRequestChangeMode', userId + ' ' + audience)
                if (audience) {
                    this.session.switchAudience(true)
                    return;
                }
                this.$alert({
                    content: '主持人邀请你参与互动',
                    cancelCallback: () => {
                        // do nothing
                    },
                    confirmCallback: () => {
                        this.session.switchAudience(false)
                    }
                })
            };

            sessionCallback.didChangeType = (userId, audience, screenSharing) => {
                console.log('didChangeType', userId, audience, screenSharing);
                this.participantUserInfos.forEach(u => {
                    if (u.uid === userId && u._isScreenSharing === screenSharing) {
                        u._isAudience = audience;
                        u._isAudioMuted = false;
                        u._isVideoMuted = false;
                        if (audience) {
                            u._stream = null;
                        }
                        if (this.speakingVideoParticipant && this.speakingVideoParticipant.uid === u.uid) {
                            this.speakingVideoParticipant = null;
                        }
                    }
                })
            };

            sessionCallback.didReportAudioVolume = (userId, volume) => {
                let userInfo;
                if (userId === this.selfUserInfo.uid) {
                    this.selfUserInfo._volume = volume;
                    userInfo = this.selfUserInfo;
                } else {
                    this.participantUserInfos.forEach(u => {
                        if (u.uid === userId && u._isScreenSharing === false) {
                            u._volume = volume;
                            userInfo = u;
                        }
                    })
                }
                if (this.currentLayout === 0) {
                    return;
                }

                if (userInfo._isVideoMuted) {
                    return;
                }

                if (this.conferenceFocusUser) {
                    return this.conferenceFocusUser;
                }

                if (!this.speakingVideoParticipant) {
                    this.speakingVideoParticipant = userInfo;
                } else if (userInfo._volume > this.speakingVideoParticipant._volume) {
                    this.speakingVideoParticipant = userInfo;
                }
            };

            sessionCallback.didMuteStateChanged = (participants) => {
                console.log('conference', 'didMuteStateChanged', participants)
                participants.forEach(p => {
                    let s = this.session.getSubscriber(p);
                    // 自己
                    if (!s) {
                        return;
                    }
                    console.log('conference', 'didMuteStateChanged', p, s.videoMuted, s.audioMuted);
                    this.participantUserInfos.forEach(u => {
                        if (u.uid === p && u._isScreenSharing === false) {
                            let subscriber = this.session.getSubscriber(p);
                            u._isVideoMuted = subscriber.videoMuted;
                            u._isAudioMuted = subscriber.audioMuted;
                            if (this.speakingVideoParticipant && this.speakingVideoParticipant.uid === u.uid) {
                                this.speakingVideoParticipant = null;
                            }
                        }
                    })

                })
            };

            sessionCallback.didMediaLostPacket = (media, lostPacket, screenSharing) => {
                console.log('didMediaLostPacket', media, lostPacket, screenSharing);
                if (lostPacket > 6) {
                    console.log('您的网络不好');
                }
            };

            sessionCallback.didUserMediaLostPacket = (userId, media, lostPacket, uplink, screenSharing) => {
                console.log('didUserMediaLostPacket', userId, media, lostPacket, uplink, screenSharing);
                //如果uplink ture对方网络不好，false您的网络不好
                //接收方丢包超过10为网络不好
                if (lostPacket > 10) {
                    if (uplink) {
                        let userInfos = this.participantUserInfos.filter(u => u.uid === userId && u._isScreenSharing === screenSharing);
                        if (userInfos && userInfos.length > 0) {
                            console.log(userInfos[0].displayName, "网络不好");
                        }
                    } else {
                        console.log('您的网络不好');
                    }
                }
            };

            avenginekit.setup(sessionCallback);
        },


        hangup() {
            this.session.leaveConference(false);
        },

        muteAudio() {
            let enable = this.session.audioMuted ? true : false;
            if (enable && !conferenceManager.isOwner() && !conferenceManager.conferenceInfo.allowSwitchMode) {
                this.requestUnmute(true);
                return;
            }
            this._muteAudio(enable);
        },

        async _muteAudio(enable) {
            let result = await this.session.setAudioEnabled(enable)
            if (!result) {
                return;
            }
            this.selfUserInfo._isAudioMuted = !enable;

            console.log('muteAudio', this.selfUserInfo._isAudioMuted, this.session.audience)
            if (enable) {
                if (this.session.audience) {
                    await this.session.switchAudience(false);
                    this.selfUserInfo._isAudience = false;
                }
            } else {
                if (this.session.videoMuted && !this.session.audience) {
                    await this.session.switchAudience(true);
                    this.selfUserInfo._isAudience = true;
                }
            }
        },
        muteVideo() {
            let enable = this.session.videoMuted ? true : false;
            if (enable && !conferenceManager.isOwner() && !conferenceManager.conferenceInfo.allowSwitchMode) {
                this.requestUnmute(false);
                return;
            }
            this._muteVideo(enable);
        },

        async _muteVideo(enable) {
            let result = await this.session.setVideoEnabled(enable)
            if (!result) {
                return;
            }
            this.selfUserInfo._isVideoMuted = !enable;

            console.log('muteVideo', this.selfUserInfo._isVideoMuted, this.session.audience)
            if (enable) {
                if (this.session.audience) {
                    await this.session.switchAudience(false);
                    this.selfUserInfo._isAudience = false;
                }
            } else {
                if (this.session.audioMuted && !this.session.audience) {
                    await this.session.switchAudience(true);
                    this.selfUserInfo._isAudience = true;
                }
            }
        },

        requestUnmute(audio) {
            this.$alert({
                content: '主持人不允许解除静音，您可以向主持人申请解除静音',
                confirmText: '申请',
                cancelCallback: () => {
                    // do nothing
                },
                confirmCallback: () => {
                    conferenceManager.applyUnmute(false);
                }
            })
        },

        down2voice() {
            this.session.downgrade2Voice();
        },

        members() {
            this.showConferenceManageView = !this.showConferenceManageView;
            this.toggleSliderView();
        },

        chat() {
            this.showConversationView = !this.showConversationView;
            this.toggleSliderView();
        },

        hideParticipantList() {
            this.showConferenceManageView && (this.showConferenceManageView = false);
            this.toggleSliderView();
        },

        toggleSliderView() {
            if (!this.showSlider) {
                if (isElectron()) {
                    let size = currentWindow.getSize();
                    currentWindow.setSize(size[0] + 350, size[1], false)
                } else {
                    window.resizeTo(window.innerWidth + 360, window.outerHeight);
                }
                this.$refs.rootContainer.style.setProperty('--slider-width', '350px');
            } else {
                if (isElectron()) {
                    let size = currentWindow.getSize();
                    this.$refs.rootContainer.style.setProperty('--slider-width', '0px');
                    currentWindow.setSize(size[0] - 350, size[1], false)
                } else {
                    this.$refs.rootContainer.style.setProperty('--slider-width', '0px');
                    window.resizeTo(window.innerWidth - 350, window.outerHeight)
                }

                this.showConferenceManageView = false;
                this.showConversationView = false;
            }
            this.showSlider = !this.showSlider;
        },


        async screenShare() {

            // if (true) {
            //     navigator.mediaDevices.enumerateDevices().then(deviceInfos => {
            //         // test input
            //         for (const deviceInfo of deviceInfos) {
            //             if (this.testCount % 2 === 0) {
            //                    //仅仅是为测试了，生成不能这么写死
            //                 if (deviceInfo.label === "外置麦克风 (Built-in)") {
            //                     console.log('audioInput 外置');
            //                     this.session.setAudioInputDeviceId(deviceInfo.deviceId);
            //                     break;
            //                 }
            //             } else {
            //                 if (deviceInfo.label === "MacBook Pro麦克风 (Built-in)") {
            //                     console.log('audioInput 内置');
            //                     this.session.setAudioInputDeviceId(deviceInfo.deviceId);
            //                     break;
            //                 }
            //             }
            //         }
            //
            //         // test output
            //         // for (const deviceInfo of deviceInfos) {
            //         //     if (this.testCount % 2 === 0) {
            //         //         if (deviceInfo.label === "外置耳机 (Built-in)") {
            //         //             console.log('audioOut 外置');
            //         //             this.setAudioOutputDeviceId(deviceInfo.deviceId)
            //         //             break;
            //         //         }
            //         //     } else {
            //         //         if (deviceInfo.label === "MacBook Pro扬声器 (Built-in)") {
            //         //             console.log('audioOutput 内置');
            //         //             this.setAudioOutputDeviceId(deviceInfo.deviceId)
            //         //             break;
            //         //         }
            //         //     }
            //         // }
            //
            //     }).catch(err => {
            //         console.log()
            //     })
            //     this.testCount++;
            //     return;
            // }

            if (this.session.isScreenSharing()) {
                this.session.stopScreenShare();
                console.log('stopScreenShare', this.session.videoMuted, this.session.audioMuted);
                if (this.session.videoMuted && this.session.audioMuted) {
                    this.session.switchAudience(true);
                }
                // currentWindow.setIgnoreMouseEvents(false)
            } else {
                if (isElectron()) {
                    let beforeClose = (event) => {
                        // What a gamble... 50% chance to cancel closing
                        if (!event.params) {
                            return;
                        }
                        if (event.params.source) {
                            let source = event.params.source;
                            let desktopShareOptions = {
                                sourceId: source.id,
                                minWidth: 1280,
                                maxWidth: 1280,
                                minHeight: 720,
                                maxHeight: 720
                            }

                            if (this.session.audience) {
                                this.session.switchAudience(false)
                                    .then(() => {
                                        this.session.startScreenShare(desktopShareOptions);
                                    })
                                    .catch(err => {
                                        console.error(err)
                                    });
                            } else {
                                this.session.startScreenShare(desktopShareOptions);
                            }
                            avenginekitproxy.emitToMain(IpcEventType.START_SCREEN_SHARE, {})
                        }
                    };
                    this.$modal.show(
                        ScreenOrWindowPicker,
                        {}, {
                            width: 800,
                            height: 600,
                            name: 'screen-window-picker-modal',
                            clickToClose: false,
                        }, {
                            // 'before-open': beforeOpen,
                            'before-close': beforeClose,
                            // 'closed': closed,
                        })
                } else {

                    if (this.session.audience) {
                        await this.session.switchAudience(false);
                    }
                    this.session.startScreenShare();
                }
            }
        },

        // 设置音频输出设备
        setAudioOutputDeviceId(deviceId) {
            let audioEls = this.$el.getElementsByTagName('audio');
            for (const audioEl of audioEls) {
                audioEl.setSinkId(deviceId);
            }
            let videoEls = this.$el.getElementsByTagName('video');
            for (const videoEl of videoEls) {
                videoEl.setSinkId(deviceId);
            }
        },

        handup() {
            conferenceManager.handUp(!conferenceManager.isHandUp)
        },

        userName(user) {
            let name = '';
            if (user.groupAlias) {
                name = user.groupAlias;
            } else if (user.friendAlias) {
                name = user.friendAlias;
            } else if (user.displayName) {
                name = user.displayName;
            } else {
                name = user.name;
            }
            return name;
        },

        timestampFormat(timestamp) {
            timestamp = ~~(timestamp / 1000);
            let str = ''
            let hour = ~~(timestamp / 3600);
            str = hour > 0 ? ((hour < 10 ? "0" : "") + hour + ':') : '';
            let min = ~~((timestamp % 3600) / 60);
            str += (min < 10 ? "0" : "") + min + ':'
            let sec = ~~((timestamp % 60));
            str += (sec < 10 ? "0" : "") + sec
            return str;
        },

        // TODO 删除，可以直接监听用户信息变化了
        refreshUserInfos() {
            let toRefreshUsers = [];
            this.participantUserInfos.forEach(pu => {
                if (!pu.updateDt) {
                    toRefreshUsers.push(pu.uid);
                }
            });

            if (toRefreshUsers.length > 0) {
                console.log('to refreshUsers', toRefreshUsers)
                IpcSub.getUserInfos(toRefreshUsers, null, (userInfos) => {
                    userInfos.forEach(u => {
                        let index = this.participantUserInfos.findIndex(p => p.uid === u.uid);
                        if (u.updateDt && index > -1) {
                            let ou = this.participantUserInfos[index];
                            u._stream = ou._stream;
                            u._isAudience = ou._isAudience;
                            u._isHost = ou._isHost;
                            u._isVideoMuted = ou._isVideoMuted;
                            u._isAudioMuted = ou._isAudioMuted;
                            u._volume = ou._volume;
                            this.participantUserInfos[index] = u;
                        }
                    })
                })
            }
        },

        rejoinConference() {
            avenginekit.joinConference({
                callId: this.session.callId,
                pin: this.session.pin,
                host: this.session.host,
                tile: this.session.title,
                desc: this.session.desc,
                audioOnly: this.session.audioOnly,
                audience: this.session.audience,
                advance: this.session.advance,
                muteVideo: this.session.videoMuted,
                muteAudio: this.session.audioMuted,
                extra: this.session.extra,
                callExtra: this.session.callExtra,
                selfUserInfo: this.selfUserInfo,
            });
            this.endReason = undefined;
        },

        prePage() {
            this.currentGridPageIndex--;
            if (this.currentGridPageIndex < 0) {
                this.currentGridPageIndex = Math.ceil(this.participantUserInfos.length / this.participantCountPerGridPage) - 1
            }
        },
        nextPage() {
            if (this.participantUserInfos.length / this.participantCountPerGridPage > (this.currentGridPageIndex + 1)) {
                this.currentGridPageIndex++;
            } else {
                this.currentGridPageIndex = 0;
            }
        },

        updateCountPerPage(count) {
            this.participantCountPerGridPage = count;
        },

        setCurrentLayout(layout) {
            if (this.currentLayout === layout) {
                return;
            }
            // 演讲者布局
            if (layout === 1) {
                // 演讲者布局，切换为小流，然后焦点用户切换为大流
                this.participantUserInfos.forEach(u => {
                    if (u.uid !== this.selfUserInfo.uid && !u._isAudience && !u._isVideoMuted) {
                        this.session.setParticipantVideoType(u.uid, u._isScreenSharing, VideoType.SMALL_STREAM);
                    }
                })
            } else {
                //宫格布局， 当前页切换为大流，未显示的，取消订阅，由 currentPageParticipants 副作用触发
                this.currentGridPageIndex = 0;
                conferenceManager.currentFocusUser = null;
            }
            this.currentLayout = layout;
            this.showChooseLayoutView = false;
        },
        toggleParticipantListVideoView() {
            this.hideFocusLayoutParticipantListVideoView = !this.hideFocusLayoutParticipantListVideoView;
        },

        hideConferenceSimpleInfoView(event) {
            if (event.target.id === 'info-icon') {
                return;
            }
            this.showConferenceSimpleInfoView = false;
        },

        hideChooseLayoutView(event) {
            if (event.target.id === 'grid-icon') {
                return;
            }
            this.showChooseLayoutView = false;
        }
    },

    computed: {
        duration() {
            if (this.currentTimestamp <= 0) {
                return '00:00'
            }
            let escapeMillis = this.currentTimestamp - this.startTimestamp;
            return this.timestampFormat(escapeMillis)
        },

        speakingUserName() {
            let maxVolume = this.selfUserInfo._volume;
            let speakingUserInfo = this.selfUserInfo;
            this.participantUserInfos.forEach(u => {
                if (u._volume > maxVolume) {
                    speakingUserInfo = u;
                    maxVolume = u._volume;
                }
            })
            if (!maxVolume) {
                return '';
            }

            return this.userName(speakingUserInfo);
        },

        currentPageParticipants() {
            if (this.currentLayout === 1) {
                return [];
            }

            let focusUser = this.conferenceFocusUser;
            // sort not in place，避免副作用
            let sortedParticipantUserInfos = [...this.participantUserInfos].sort((o1, o2) => {
                if (focusUser) {
                    if (o1.uid === focusUser.uid && o1._isScreenSharing === focusUser._isScreenSharing) {
                        return -1;
                    }
                    if (o2.uid === focusUser.uid && o2._isScreenSharing === focusUser._isScreenSharing) {
                        return 1;
                    }
                }

                if (o1._isAudience && !o2._isAudience) {
                    return 1;
                } else if (!o1._isAudience && o2._isAudience) {
                    return -1;
                } else if (o1._isAudience && o2._isAudience) {
                    return o1.uid.localeCompare(o2.uid);
                } else {
                    if (o1._isScreenSharing && !o2._isScreenSharing) {
                        return -1;
                    }
                    if (!o1._isScreenSharing && o2._isScreenSharing) {
                        return 1;
                    }
                    if (!o1._isVideoMuted && o2._isVideoMuted) {
                        return -1;
                    }
                    if (o1._isVideoMuted && !o2._isVideoMuted) {
                        return 1;
                    }
                    return o1.uid.localeCompare(o2.uid);
                }
            })

            let start = this.currentGridPageIndex * this.participantCountPerGridPage;
            let end = start + this.participantCountPerGridPage > sortedParticipantUserInfos.length ? sortedParticipantUserInfos.length : (start + this.participantCountPerGridPage);
            // side effect
            // TODO 优化
            // 相邻页切换时，不能理解取消订阅，可能还切换回去，那样的话，就会有一小段时间，不显示视频流
            for (let i = 0; i < sortedParticipantUserInfos.length; i++) {
                let u = sortedParticipantUserInfos[i];
                if (u.uid === this.selfUserInfo.uid || u._isAudience || u._isVideoMuted) {
                    continue;
                }
                if (i >= start && i < end) {
                    console.log('set video type big', u.uid)
                    this.session.setParticipantVideoType(u.uid, u._isScreenSharing, VideoType.BIG_STREAM);
                } else {
                    console.log('set video type none', u.uid)
                    this.session.setParticipantVideoType(u.uid, u._isScreenSharing, VideoType.NONE);
                }
            }
            // side effect
            return sortedParticipantUserInfos.slice(start, end);
        },

        gridPageCount() {
            return Math.ceil(this.participantUserInfos.length / this.participantCountPerGridPage);
        },

        conferenceFocusUser() {
            let focus = conferenceManager.conferenceInfo.focus;
            if (!focus) {
                return null;
            }
            let focusUser = this.participantUserInfos.find(u => u.uid === focus && u._isScreenSharing === true);
            if (!focusUser) {
                focusUser = this.participantUserInfos.find(u => u.uid === focus);
            }
            return focusUser;
        },
        conferenceLocalFocusUser() {
            return conferenceManager.localFocusUser;
        },

        // 以用户手动选择的为准
        computedCurrentLayout() {
            if (this.currentLayout === -1 && this.conferenceFocusUser) {
                return 1;
            }
            return this.currentLayout;
        },

        // TODO 可以缓存到 conferenceManager 里面
        computedFocusVideoParticipant() {
            if (this.currentLayout === 0) {
                return null;
            }
            let sp;
            if (this.conferenceFocusUser && !this.conferenceFocusUser._isVideoMuted) {
                sp = this.conferenceFocusUser;
            } else if (this.conferenceLocalFocusUser && !this.conferenceLocalFocusUser._isVideoMuted) {
                sp = this.conferenceLocalFocusUser;
            } else if (this.speakingVideoParticipant) {
                sp = this.speakingVideoParticipant;
            } else {
                sp = this.participantUserInfos.find(u => !u._isAudience && !u._isVideoMuted && u._isScreenSharing === true);
                if (!sp) {
                    sp = this.participantUserInfos.find(u => !u._isAudience && !u._isVideoMuted);
                }
            }

            if (conferenceManager.currentFocusUser) {
                this.session.setParticipantVideoType(conferenceManager.currentFocusUser.uid, conferenceManager.currentFocusUser._isScreenSharing, VideoType.SMALL_STREAM);
            }
            conferenceManager.currentFocusUser = sp;
            this.session.setParticipantVideoType(conferenceManager.currentFocusUser.uid, conferenceManager.currentFocusUser._isScreenSharing, VideoType.BIG_STREAM);
            console.log('computedSpeakingParticipant', sp)
            return sp;
        }
    },

    watch: {
        participantUserInfos: {
            deep: true,
            handler(infos) {
                let audioOnly = true;
                for (let i = 0; i < this.participantUserInfos.length; i++) {
                    let u = this.participantUserInfos[i];
                    if (!u._isAudience && !u._isVideoMuted) {
                        audioOnly = false;
                        break;
                    }
                }
                this.audioOnly = audioOnly;

                if (this.audioOnly) {
                    let ref = this.$refs[this.selfUserInfo.uid + '-audio'];
                    if (ref && ref.length > 0) {
                        this.$refs[this.selfUserInfo.uid + '-audio'][0].muted = true;
                    }
                    return;
                }
                // 宫格布局
                if (this.currentLayout === 0) {
                    let start = this.currentGridPageIndex * this.participantCountPerGridPage;
                    let end = start + this.participantCountPerGridPage > this.participantUserInfos.length ? this.participantUserInfos.length : (start + this.participantCountPerGridPage);
                    let count = end - start;
                    let width = '100%';
                    let height = '100%';
                    if (count <= 1) {
                        width = '100%';
                        height = '100%';
                    } else if (count <= 4) {
                        width = '50%';
                        height = '45%';
                    } else if (count <= 9) {
                        width = '33%';
                        height = '33%'
                    } else {
                        // max 16
                        width = '25%';
                        height = '25%'
                    }
                    if (this.$refs.rootContainer) {
                        this.$refs.rootContainer.style.setProperty('--participant-video-item-width', width);
                        this.$refs.rootContainer.style.setProperty('--participant-video-item-height', height);
                    }
                }

                // mute self audio
                let ref = this.$refs[this.selfUserInfo.uid + '-audio'];
                if (ref && ref.length > 0) {
                    this.$refs[this.selfUserInfo.uid + '-audio'][0].muted = true;
                }
            }
        },
        currentPageParticipants: {
            deep: true,
            handler(infos) {
                if (this.audioOnly) {
                    return;
                }
                if (this.currentLayout === 0) {
                    let count = this.currentPageParticipants.length;
                    let width = '100%';
                    let height = '100%';
                    if (count <= 1) {
                        width = '100%';
                        height = '100%';
                    } else if (count <= 4) {
                        width = '50%';
                        height = '45%';
                    } else if (count <= 9) {
                        width = '33%';
                        height = '33%'
                    } else {
                        // max 16
                        width = '25%';
                        height = '25%'
                    }
                    if (this.$refs.rootContainer) {
                        this.$refs.rootContainer.style.setProperty('--participant-video-item-width', width);
                        this.$refs.rootContainer.style.setProperty('--participant-video-item-height', height);
                    }
                }
            }
        }
    },

    directives: {
        ClickOutside
    },

    created() {
        document.title = '在线会议';
        conferenceManager.setVueInstance(this);
        this.refreshUserInfoInternal = setInterval(() => {
            this.refreshUserInfos();
        }, 3 * 1000)

        this.$eventBus.$on('muteVideo', (mute) => {
            if (this.session.videoMuted !== mute) {
                let enable = this.session.videoMuted ? true : false;
                this._muteVideo(enable);
            }
        })
        this.$eventBus.$on('muteAudio', (mute) => {
            if (this.session.audioMuted !== mute) {
                let enable = this.session.audioMuted ? true : false;
                this._muteAudio(enable);
            }
        })
    },

    mounted() {
        this.setupSessionCallback();

        if (isElectron()) {
            //
            // this.$on('stop-screen-share', () => {
            //     this.session.stopScreenShare();
            //     this.$forceUpdate();
            // })
            window.addEventListener("mousemove", (event) => {
                if (!this.session || !this.session.isScreenSharing()) {
                    return;
                }
                if (event.target.id === "main-content-container") {
                    currentWindow.setIgnoreMouseEvents(true, {forward: true});
                } else {
                    currentWindow.setIgnoreMouseEvents(false);
                }
            });
            window.addEventListener("mouseleave", (event) => {
                currentWindow.setIgnoreMouseEvents(false);
            })
            this.$refs.rootContainer.style.setProperty('--conference-container-margin-top', '30px');
        } else {
            this.$refs.rootContainer.style.setProperty('--conference-container-margin-top', '0px');
        }
    },

    destroyed() {
        // reset
        this.$set(this.selfUserInfo, '_stream', null)
        this.participantUserInfos.forEach(m => this.$set(m, "_stream", null))
        clearInterval(this.refreshUserInfoInternal);
        this.$eventBus.$off('muteVideo');
        this.$eventBus.$off('muteAudio');
    }
}
</script>

<style lang="css" scoped>

.voip-container {
    background: #00000000 !important;
    position: relative;
    --conference-container-margin-top: 30px;
    --slider-width: 0px;
    --main-width: 100%;
}

a {
    color: gray;
}

i:hover {
    color: #1f64e4;
}

i.active {
    color: #3f64e4;
}

.main-slider-container {
    width: 100vw;
    margin-top: var(--conference-container-margin-top);
    height: calc(100vh - var(--conference-container-margin-top));
    display: flex;
    flex-direction: row;
}

.main-slider-container .main {
    width: calc(100% - var(--slider-width));
    height: 100%;
}

.main-slider-container .slider {
    width: var(--slider-width);
    height: 100%;
    overflow: auto;
    background: white;
}

.conference-main-content-container {
    width: 100%;
    height: calc(100% - 20px);
    position: relative;
    /*flex: 1;*/
    /*flex-direction: column;*/
    /*justify-content: space-between;*/
    /*align-items: center;*/
}

.content-container {
    width: 100%;
    height: 100%;
    position: relative;
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    align-content: center;
}

.main-slider-container .grid {
    flex-direction: row;
}

.main-slider-container .focus {
    --participant-video-item-width: 200px;
    --participant-video-item-height: 100px;
    flex-direction: column;
}

.content-container.video {
    background: black;
    object-fit: contain;
}

.focus-mode-participant-list-container {
    /*position: absolute;*/
    /*top: 0;*/
    /*right: 0;*/
    width: 200px;
    height: 100%;
    overflow: auto;
}

.content-container.audio {
    background: white;
    height: calc(100% - 50px);
    overflow: auto;
    padding: 10px 0 50px 0;
}

.participant-audio-item {
    display: flex;
    flex-direction: column;
    padding: 20px 40px;
    justify-content: center;
    align-items: center;
}

.hidden-video {
    height: 0;
}

.participant-audio-item .indicator {
    width: 18px;
    height: 18px;
    position: absolute;
    left: 50%;
    color: white;
    text-align: center;
    vertical-align: center;
    border-radius: 9px;
    bottom: 0;
    background: #d6d6d6;
    transform: translateX(-50%) translateY(25%);
}

.participant-audio-item p {
    padding-top: 8px;
}

.conference-main-content-container:hover footer {
    width: 100%;
    display: block;
    position: absolute;
    left: 0;
    bottom: 0;
    background: gray;
}

footer {
    /*height: 100px;*/
    display: none;
}

.duration-action-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.duration-action-container p {
    color: white;
    padding: 0 5px 0 0;
}

.action-container {
    /*width: 100%;*/
    display: flex;
    justify-content: center;
}

.action-container .action {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    font-size: 12px;
    color: white;
    padding: 0 25px 0 25px;
}

.avatar {
    width: 90px;
    height: 90px;
    border-radius: 45px;
}

.avatar.highlight {
    border: 2px solid #1FCA6A;
}

.action-img {
    width: 40px;
    height: 40px;
}

.video.me {
    -webkit-transform: scaleX(-1);
    transform: scaleX(-1);
}

.rejoin-container {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: #e0e0e0e0;
    text-align: center;
    justify-content: center;
    color: red;
}

.icon-ion-grid:after {
    padding-left: 5px;
    content: "\f13f";
}

</style>
